#include "daemon_runner.h"
#include "daemon_process.h"
#include "thirdparty/log.c/log.h"
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/reboot.h>

#define SUBPROCESS_COUNT 2

int running = 1;
int subprocess_restart_count = 0;

void daemon_runner_signalHandler(int sig)
{
    log_debug("Receive signal %d", sig);
    running = 0;
}

void daemon_runner_run()
{
    log_set_level(LOG_DEBUG);
    // 将该进程设置为守护进程
    if (daemon(0, 1) < 0)
    {
        log_error("Daemonize error");
        exit(EXIT_FAILURE);
    }

    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    open("/dev/null", O_RDWR);
    open(LOG_FILE, O_RDWR | O_CREAT, 0644);
    open(LOG_FILE, O_RDWR | O_CREAT, 0644);

    Subprocess subprocess[SUBPROCESS_COUNT];
    // 声明子进程
    daemon_process_init(subprocess, "app");
    daemon_process_init(subprocess + 1, "ota");

    // 启动子进程
    daemon_process_run(subprocess);
    daemon_process_run(subprocess + 1);

    signal(SIGTERM, daemon_runner_signalHandler);

    // 如果子进程挂掉，重启子进程
    while (running)
    {
        pid_t pid = waitpid(-1, NULL, WNOHANG);
        if (pid < 0)
        {
            log_warn("Waitpid error");
            continue;
        }
        else if (pid == 0)
        {
            log_trace("No child process exit");
            continue;
        }
        else
        {
            for (int i = 0; i < SUBPROCESS_COUNT; i++)
            {
                if (subprocess[i].pid == pid)
                {
                    log_warn("Child process %s exit", subprocess[i].argv[1]);
                    subprocess_restart_count++;
                    if (subprocess_restart_count > 10)
                    {
                        log_fatal("Current binary not stable, rollbacking...");
                        int fd = open("/tmp/gateway.error", O_CREAT | O_RDWR, 0644);
                        close(fd);
                        reboot(RB_AUTOBOOT);
                    }
                    
                    daemon_process_run(subprocess + i);
                }
            }
        }
        // 每100ms查看一次子进程状态
        usleep(100000);
    }

    log_info("Terminating...");
    for (int i = 0; i < SUBPROCESS_COUNT; i++)
    {
        kill(subprocess[i].pid, SIGTERM);
        waitpid(subprocess[i].pid, NULL, 0);
    }
    log_info("Terminated");
}